﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace Lyon.Utility
{
    /// <summary>
    /// 求点、矩形之间关系的工具
    /// </summary>
    static public class NearestRect
    {
        /// <summary>
        /// 获取指定点在矩形内最近的点。
        /// </summary>
        /// <param name="rect">矩形</param>
        /// <param name="point">指定点</param>
        /// <returns></returns>
        static public Point GetNearestPoint(Rectangle rect, Point point)
        {
            if (point.X > rect.Right)
            {
                point.X = rect.Right;
            }
            else if (point.X < rect.Left)
            {
                point.X = rect.Left;
            }
            if (point.Y > rect.Bottom)
            {
                point.Y = rect.Bottom;
                return point;
            }
            if (point.Y < rect.Top)
            {
                point.Y = rect.Top;
            }
            return point;
        }
        /// <summary>
        /// 获取指定小矩形在大矩形内最近的矩形。
        /// </summary>
        /// <param name="main">大矩形</param>
        /// <param name="smallRect">指定小矩形</param>
        /// <returns></returns>
        static public Rectangle GetNearestRect(Rectangle main, Rectangle smallRect)
        {
            if (main.Width < smallRect.Width || main.Height < smallRect.Height)
                throw new ArgumentException("小矩形超出大矩形的范围.", "smallRect");
            Point location = smallRect.Location;
            Point point = new Point(smallRect.Right, smallRect.Top);
            Point nearestPoint = new Point(smallRect.Right, smallRect.Bottom);
            Point point4 = new Point(smallRect.Left, smallRect.Bottom);
            if (!RectangleContainsPoint(main, location))
            {
                location = GetNearestPoint(main, location);
                smallRect.Location = location;
            }
            else if (!RectangleContainsPoint(main, point))
            {
                point = GetNearestPoint(main, point);
                smallRect.Location = new Point(point.X - smallRect.Width, point.Y);
            }
            else if (!RectangleContainsPoint(main, nearestPoint))
            {
                nearestPoint = GetNearestPoint(main, nearestPoint);
                smallRect.Location = new Point(nearestPoint.X - smallRect.Width, nearestPoint.Y - smallRect.Height);
            }
            else if (!RectangleContainsPoint(main, point4))
            {
                point4 = GetNearestPoint(main, point4);
                smallRect.Location = new Point(point4.X, point4.Y - smallRect.Height);
            }
            if (main.Contains(smallRect))
            {
                return smallRect;
            }
            return GetNearestRect(main, smallRect);
        }
        /// <summary>
        /// 判断指定点是否在矩形内
        /// </summary>
        /// <param name="rect">矩形</param>
        /// <param name="point">指定点</param>
        /// <returns></returns>
        static public bool RectangleContainsPoint(Rectangle rect, Point point)
        {
            return (((point.X >= rect.Left) && (point.X <= rect.Right)) && ((point.Y >= rect.Top) && (point.Y <= rect.Bottom)));
        }
        /// <summary>
        /// 判断指定小矩形是否在大矩形内
        /// </summary>
        /// <param name="main">大矩形</param>
        /// <param name="smallRect">小矩形</param>
        /// <returns></returns>
        static public bool RectangleContainsRectangle(Rectangle main, Rectangle smallRect)
        {
            return main.Contains(smallRect);
        }
    }
}
